# calc_utils.py
"""
纯计算函数：单位换算 / DPI 计算
完全不依赖 Tkinter，只依赖标准库和 math
"""
import math

def convert_to_pixels(value, unit, dpi):
    """将不同单位的值转换为像素

    Args:
        value: 要转换的值，可以是字符串或数值
        unit: 单位，可以是"cm"、"inch"或"pixel"
        dpi: DPI值，用于转换

    Returns:
        float 或 int: 转换后的像素值，在单位为pixel时返回整数
    """
    try:
        value = float(value)
        dpi = float(dpi)
        if unit == "cm":
            # 将厘米转换为像素: 厘米 / 2.54 * DPI = 英寸 * DPI = 像素
            # 使用精确计算，不在这里取整，以保持计算精度
            return value / 2.54 * dpi
        elif unit == "inch":
            # 将英寸转换为像素: 英寸 * DPI = 像素
            # 同样不在这里取整
            return value * dpi
        else:  # pixel
            # 像素单位直接返回，确保是整数
            return int(round(value))
    except ValueError:
        return 0

def convert_from_pixels(pixels, unit, dpi):
    """将像素值转换为指定单位

    Args:
        pixels: 像素值
        unit: 目标单位，可以是"cm"、"inch"或"pixel"
        dpi: DPI值，用于转换

    Returns:
        float: 转换后的值
    """
    try:
        pixels = float(pixels)
        dpi = float(dpi)
        if unit == "cm":
            # 转换为厘米: 像素 / DPI * 2.54 = 英寸 * 2.54 = 厘米
            return pixels * 2.54 / dpi
        elif unit == "inch":
            # 转换为英寸: 像素 / DPI = 英寸
            return pixels / dpi
        else:  # pixel
            # 像素单位直接返回
            return pixels
    except ValueError:
        return 0
        
def calculate_optimal_dpi_for_image(original_width, original_height, target_width_inch, target_height_inch):
    """为单张图片计算最优DPI"""
    # 默认DPI
    default_dpi = 300.0
    
    # 计算原图的像素总数
    original_pixels = original_width * original_height
    
    # 设置质量保护因子（保持至少70%的像素数量）
    quality_factor = 0.7
    min_target_pixels = original_pixels * quality_factor
    
    # 计算目标像素总数
    target_area_sqinch = target_width_inch * target_height_inch
    
    # 计算需要的DPI以保持质量
    # pixels = dpi² × area_sqinch
    # required_dpi = √(min_target_pixels / target_area_sqinch)
    required_dpi = math.sqrt(min_target_pixels / target_area_sqinch)
    
    # 另一种方法：基于宽高分别计算DPI
    required_dpi_width = (original_width * quality_factor ** 0.5) / target_width_inch
    required_dpi_height = (original_height * quality_factor ** 0.5) / target_height_inch
    required_dpi_alt = min(required_dpi_width, required_dpi_height)
    
    # 取两种方法的较小值（更保守）
    suggested_dpi = max(default_dpi, min(required_dpi, required_dpi_alt))
    
    # 限制DPI在合理范围内（72-3000）
    suggested_dpi = max(72, min(3000, suggested_dpi))
    
    return suggested_dpi